<?php
namespace app\api\controller;
use think\Controller;
use think\Db;
use lib\Curl;
use lib\UserCrypt;
class Money extends Base{
    private $key='eih0cfnmokla4nxwo4w0ioqvmtracc1c';
    public function cashOut()
    {
        if(!empty(input("param.token"))){
            $token=input("param.token");
        }else{
            return json(['code' => 501, 'msg' => '令牌呢？']);
        }
        if(input("param.style")==1||input("param.style")==2){
            $data['style']=input("param.style");
        }else{
            return json(['code' => 501, 'msg' => '线上还是线下？']);
        }
        if(!empty(input("param.cashes"))){
                $cashes=input("param.cashes");
        }else{
            return json(['code' => 502, 'msg' => '提现金额呢？']);
        }
        if($cashes<1){
            return json(['code' => 503, 'msg' => '提现金额不能低于1元']);
        }
        if (preg_match('/^[0-9]+(.[0-9]{1,2})?$/',$cashes)) {
        }else{
            return json(['code' => 504, 'msg' => '请输入整数或两位小数的金额']);
        }
        $uid=UserCrypt::do_mdecrypt($token);
        $orderno=date('YmdHis',time()).mt_rand(1111,9999);
        $openid=Db::name('users')->where('id',$uid)->find();
        if($openid['money']<$cashes){
            return json(['code' => 506, 'msg' => '不能高于可提现金额']);
        }
        if($data['style']==2){
            if(!empty(input("param.name"))){
                $data['name']=input("param.name");
            }else{
                return json(['code' => 501, 'msg' => '姓名']);
            }
            if(!empty(input("param.card_no"))){
                $data['card_no']=input("param.card_no");
            }else{
                return json(['code' => 501, 'msg' => '卡号或账号']);
            }
            if(!empty(input("param.bank"))){
                $data['bank']=input("param.bank");
            }
            $cashing=Db::name('cashout')->where('user_id',$uid)->where('state',1)->find();
            if($cashing){
                return json(['code' => 507, 'msg' => '有提现申请还未处理！']);
            }
            $data['user_id']=$uid;
            $data['orderno']=$orderno;
            $data['cash']=$cashes;
            $data['state']=1;
            $data['time']=time();
            $data['uptime']=time();
            $cashId=Db::name('cashout')->insertGetId($data);
            if($cashId){
                Db::name('users')->where('id', $uid)->setDec('money',$cashes);
                return json(['code' => 200, 'msg' => '申请成功！']);
            }else{
                return json(['code' => 500, 'msg' => '失败！']);
            }
        }
        if($data['style']==1){
            if($openid['openid']){

            }else{
                return json(['code' => 505, 'msg' => '未授权获取openid,请前往公众号授权或试试其他提现方式!']);
            }
            $data['user_id']=$uid;
            $data['orderno']=$orderno;
            $data['cash']=$cashes;
            $data['state']=1;
            $data['time']=time();
            $data['uptime']=time();
            $cashId=Db::name('cashout')->insertGetId($data);
            $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
            $parameters = array(
                'mch_appid' => 'wx73b2fe7a7e0dab2c',
                'mchid' => '1375626302',
                'nonce_str' => $this->createNoncestr(),
                'partner_trade_no' => $orderno,
                'openid' => $openid['openid'],
                'check_name' => 'NO_CHECK',
                'amount' => floatval($cashes*100),//100=1元
                'desc' => '提现'
            );
            $parameters['sign']=$this->getSign($parameters);
            $xmlData = $this->arrayToXml($parameters);
            $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60));
            if($return['return_code']&&$return['result_code']){
                Db::name('money_bill')->insert(['user_id'=>$uid,'orders_id'=>0,'orderno'=>$orderno,'type'=>3,'money'=>$cashes,'time'=>time(),'uptime'=>time()]);
                Db::name('cashout')->where('id',$cashId)->where('user_id',$uid)->where('orderno',$orderno)->update(['state'=>2,'uptime'=>time()]);
                Db::name('users')->where('id', $uid)->setDec('money',$cashes);
                return json(['code' => 200, 'msg' => $return['return_msg']]);
            }else{
                return json(['code' => 500, 'msg' => $return['return_msg'].'请试试其他提现方式!']);
            }
        }
        
        
    }
    //xml转换成数组
    private function xmlToArray($xml) {


        //禁止引用外部xml实体 


        libxml_disable_entity_loader(true);


        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);


        $val = json_decode(json_encode($xmlstring), true);


        return $val;
    }
    //数组转换成xml
    private function arrayToXml($arr) {
        $xml = "<root>";
        foreach ($arr as $key => $val) {
            if (is_array($val)) {
                $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
        }
        $xml .= "</root>";
        return $xml;
    }
    private static function postXmlCurl($xml, $url, $second = 30) 
    {
        $isdir = $_SERVER['DOCUMENT_ROOT'];
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验

          curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型
          curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置
          curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型
          curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置
          curl_setopt($ch, CURLOPT_CAINFO, 'PEM');
          curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem');

        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);


        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
        curl_setopt($ch, CURLOPT_TIMEOUT, 40);
        set_time_limit(0);


        //运行curl
        $data = curl_exec($ch);
        //返回结果
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            throw new WxPayException("curl出错，错误码:$error");
        }
    }
    //作用：产生随机字符串，不长于32位
    private function createNoncestr($length = 32) {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    //作用：生成签名
    private function getSign($Obj) {
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //签名步骤二：在string后加入KEY
        $String = $String . "&key=" . $this->key;
        //签名步骤三：MD5加密
        $String = md5($String);
        //签名步骤四：所有字符转为大写
        $result_ = strtoupper($String);
        return $result_;
    }
    //作用：格式化参数，签名过程需要使用
    private function formatBizQueryParaMap($paraMap, $urlencode) {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar;
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }
}